package dolf.objects;

import dolf.objects.WorldObject;

public class Point implements java.io.Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private double x;
	private double y;
	public Point(double xv, double yv){
		x = xv;
		y = yv;
	}
	
	public Point(int xv,int yv){
		x = xv;
		y = yv;
	}
	
	public double getX(){
		return x;
	}
	public double getY(){
		return y;
	}
	public int getIntX(){
		return (int) Math.round(x);	
	}
	public int getIntY(){
		return (int) Math.round(y);
	}
	public void setX(double x){
		this.x = x;
	}
	public void setY(double y){
		this.y = y;
	}
	public Point add(Vector vec){
		return new Point(this.x + vec.getX(), this.y + vec.getY());
	}
	public Point add(Point vec){
		return new Point(this.x + vec.getX(), this.y + vec.getY());
	}
	public Point sub(Vector vec){
		return new Point(this.x - vec.getX(), this.y - vec.getY());
	}
	public Vector sub(Point point){
		return new Vector(this.getX()-point.getX(), this.getY()-point.getY());
	}
	public double getDist(Point point){
		return Math.sqrt(((this.getX()-point.getX())*(this.getX()-point.getX()))+((this.getY()-point.getY())*(this.getY()-point.getY())));
	}
	public Point getCopy(){
		return (new Point(this.x, this.y));
	}
	private double distToLineCircles(LineObject l){
		return Math.min(this.getDist(l.getEnd()), this.getDist(l.getPosition()))-l.getCircleP1().getRadius();
	}
	public double getDist(WorldObject object){
		if(object instanceof LineObject){
			LineObject obj = (LineObject) object;
			// Faellt das Lot durch this auf obj;
			// Loese nach CRAMER
			// det Determinante
			//(obj.getNormVec.x		obj.getDirection.x	) 	(x)		
			//(											)	( ) = 
			//(obj.getNormVec.y		obj.getDirection.y	)	(y)
			double det = obj.getNormVec().getX() * obj.getDirection().getY() - obj.getNormVec().getY()*obj.getDirection().getX(); 
			if(det == 0){ // Fall Parallel oder Identisch
				//System.out.println("Fehler!!!!! Darf nicht Sein !!!");
				return distToLineCircles(obj); // 
			} else {
				// Berechntet Schnittpunkt s;
				//System.out.println(obj.getNormVec().getX()+" , "+obj.getNormVec().getY());
				Point S = obj.getIntersection(this, obj.getNormVec());
				if(S == null){
					return distToLineCircles(obj); 					
				}
				if((S.getX() >= obj.getPosition().getX() && S.getX() <= obj.getEnd().getX())
					|| (S.getX() <= obj.getPosition().getX() && S.getX() >= obj.getEnd().getX())){
					// S liegt auf Linie
					//System.out.println(S.getX()+" , "+S.getY());
					return this.getDist(S);
				} else {
					// S liegt nicht auf Linie
					//System.out.println("nicht auf gerade");
					return Math.min(this.getDist(obj.getPosition()), this.getDist(obj.getEnd()));
				}
			}
		}
		if(object instanceof CircleObject){
			return Math.sqrt((this.getX()- object.getPosition().getX())*(this.getX()- object.getPosition().getX())+ (this.getY()- object.getPosition().getY())*(this.getY()- object.getPosition().getY()));
		}
		return -1;
	}
	public String print(){
		return " (" + this.x + " , " + this.y + ") ";
	}
}
